# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.1069.1.201+1.1069.48.59 -> 1.1069.153.1 # drivers/char/drm/drm_agpsupport.h 1.10.1.7 -> 1.18 # include/linux/sysctl.h 1.23.1.15 -> 1.31.1.3 # mm/page_alloc.c 1.56.1.9 -> 1.62.1.2 # include/linux/sched.h 1.33.1.9 -> 1.37.1.4 # arch/ia64/kernel/setup.c 1.11.3.6 -> 1.11.2.3 # drivers/char/Config.in 1.36.1.24 -> 1.39.1.15 # include/asm-ppc/pgtable.h 1.18.1.5 -> 1.23 # include/linux/fs.h 1.69.1.26 -> 1.76.1.6 # drivers/net/Makefile 1.29.1.12 -> 1.33.1.7 # drivers/char/serial.c 1.33.1.5 -> 1.45 # arch/i386/config.in 1.43.1.6 -> 1.44.1.4 # include/linux/pci_ids.h 1.44.1.37 -> 1.46.1.24 # drivers/net/tg3.c 1.61.2.48 -> 1.62.1.10 # arch/ia64/mm/init.c 1.7.4.4 -> 1.7.3.3 # drivers/scsi/Config.in 1.15.1.7 -> 1.18.1.5 # arch/i386/kernel/setup.c 1.68.1.10 -> 1.70.1.8 # arch/ia64/kernel/acpi.c 1.6.3.16 -> 1.6.4.5 # drivers/pci/pci.ids 1.44.1.4 -> 1.46.1.1 # include/asm-ia64/xor.h 1.1.1.1 -> 1.2.1.1 # fs/Makefile 1.16.1.4 -> 1.20.1.1 # arch/ia64/hp/common/sba_iommu.c 1.1.2.15 -> 1.1.3.3 # fs/Config.in 1.20.1.8 -> 1.28.1.2 # Makefile 1.190.1.67 -> 1.193.1.40 # drivers/scsi/Makefile 1.19.1.4 -> 1.20.1.5 # include/asm-m68k/pgtable.h 1.3.1.1 -> 1.5 # Documentation/Configure.help 1.162.1.51 -> 1.166.1.22 # drivers/char/Makefile 1.27.1.11 -> 1.31.1.6 # fs/inode.c 1.36.1.8 -> 1.40.1.4 # arch/ia64/config.in 1.13.5.7 -> 1.13.4.6 # diff -Nru a/Documentation/Configure.help b/Documentation/Configure.help --- a/Documentation/Configure.help Fri Dec 12 16:27:40 2003 +++ b/Documentation/Configure.help Fri Dec 12 16:27:40 2003 @@ -18478,6 +18478,11 @@ purpose port, say Y here. See . +Support for serial ports defined in ACPI namespace +CONFIG_SERIAL_ACPI + If you wish to enable serial port discovery via the ACPI + namespace, say Y here. If unsure, say N. + Support for PowerMac serial ports CONFIG_MAC_SERIAL If you have Macintosh style serial ports (8 pin mini-DIN), say Y diff -Nru a/Makefile b/Makefile --- a/Makefile Fri Dec 12 16:27:40 2003 +++ b/Makefile Fri Dec 12 16:27:40 2003 @@ -93,6 +93,7 @@ CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \ -fno-strict-aliasing -fno-common +CFLAGS += -g ifndef CONFIG_FRAME_POINTER CFLAGS += -fomit-frame-pointer endif @@ -306,8 +307,7 @@ $(CONFIG_SHELL) scripts/Configure -d arch/$(ARCH)/config.in xconfig: symlinks - $(MAKE) -C scripts kconfig.tk - wish -f scripts/kconfig.tk + @echo -e "***\n* Sorry, xconfig is broken; use \"make menuconfig\" instead.\n***" menuconfig: include/linux/version.h symlinks $(MAKE) -C scripts/lxdialog all diff -Nru a/arch/ia64/config.in b/arch/ia64/config.in --- a/arch/ia64/config.in Fri Dec 12 16:27:40 2003 +++ b/arch/ia64/config.in Fri Dec 12 16:27:40 2003 @@ -84,6 +84,30 @@ define_bool CONFIG_KCORE_ELF y # On IA-64, we always want an ELF /proc/kcore. +define_int CONFIG_FORCE_MAX_ZONEORDER 19 + +if [ "$CONFIG_HUGETLB_PAGE" = "y" ]; then + if [ "$CONFIG_MCKINLEY" = "y" ]; then + choice ' IA-64 Huge TLB Page Size' \ + "4GB CONFIG_HUGETLB_PAGE_SIZE_4GB \ + 1GB CONFIG_HUGETLB_PAGE_SIZE_1GB \ + 256MB CONFIG_HUGETLB_PAGE_SIZE_256MB \ + 64MB CONFIG_HUGETLB_PAGE_SIZE_64MB \ + 16MB CONFIG_HUGETLB_PAGE_SIZE_16MB \ + 4MB CONFIG_HUGETLB_PAGE_SIZE_4MB \ + 1MB CONFIG_HUGETLB_PAGE_SIZE_1MB \ + 256KB CONFIG_HUGETLB_PAGE_SIZE_256KB" 16MB + else + choice ' IA-64 Huge TLB Page Size' \ + "256MB CONFIG_HUGETLB_PAGE_SIZE_256MB \ + 64MB CONFIG_HUGETLB_PAGE_SIZE_64MB \ + 16MB CONFIG_HUGETLB_PAGE_SIZE_16MB \ + 4MB CONFIG_HUGETLB_PAGE_SIZE_4MB \ + 1MB CONFIG_HUGETLB_PAGE_SIZE_1MB \ + 256KB CONFIG_HUGETLB_PAGE_SIZE_256KB" 16MB + fi +fi + bool 'Use PAL_HALT_LIGHT in idle loop' CONFIG_IA64_PAL_IDLE bool 'SMP support' CONFIG_SMP if [ "$CONFIG_SMP" = "y" ]; then diff -Nru a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c --- a/arch/ia64/hp/common/sba_iommu.c Fri Dec 12 16:27:39 2003 +++ b/arch/ia64/hp/common/sba_iommu.c Fri Dec 12 16:27:40 2003 @@ -138,6 +138,7 @@ #define ZX1_IOC_ID ((PCI_DEVICE_ID_HP_ZX1_IOC << 16) | PCI_VENDOR_ID_HP) #define REO_IOC_ID ((PCI_DEVICE_ID_HP_REO_IOC << 16) | PCI_VENDOR_ID_HP) +#define SX1000_IOC_ID ((PCI_DEVICE_ID_HP_SX1000_IOC << 16) | PCI_VENDOR_ID_HP) #define ZX1_IOC_OFFSET 0x1000 /* ACPI reports SBA, we want IOC */ @@ -1637,6 +1638,7 @@ static struct ioc_iommu ioc_iommu_info[] __initdata = { { ZX1_IOC_ID, "zx1", ioc_zx1_init }, { REO_IOC_ID, "REO" }, + { SX1000_IOC_ID, "sx1000" }, }; static struct ioc * __init diff -Nru a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c --- a/arch/ia64/kernel/acpi.c Fri Dec 12 16:27:39 2003 +++ b/arch/ia64/kernel/acpi.c Fri Dec 12 16:27:39 2003 @@ -820,4 +820,22 @@ return gsi_to_vector(irq); } +int +acpi_register_irq (u32 gsi, u32 polarity, u32 trigger) +{ + int vector = 0; + + if (has_8259 && gsi < 16) + return isa_irq_to_vector(gsi); + + if (!iosapic_register_intr) + return 0; + + /* Turn it on */ + vector = iosapic_register_intr(gsi, + (polarity == ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW, + (trigger == ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE : IOSAPIC_LEVEL); + return vector; +} + #endif /* CONFIG_ACPI_BOOT */ diff -Nru a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c --- a/arch/ia64/kernel/setup.c Fri Dec 12 16:27:39 2003 +++ b/arch/ia64/kernel/setup.c Fri Dec 12 16:27:39 2003 @@ -46,6 +46,7 @@ #include #include #include +#include #ifdef CONFIG_BLK_DEV_RAM # include @@ -64,6 +65,7 @@ struct cpuinfo_ia64 *_cpu_data[NR_CPUS]; #else struct cpuinfo_ia64 _cpu_data[NR_CPUS] __attribute__ ((section ("__special_page_section"))); + mmu_gather_t mmu_gathers[NR_CPUS]; #endif unsigned long ia64_cycles_per_usec; @@ -659,6 +661,7 @@ _cpu_data[cpu]->cpu_data[smp_processor_id()] = my_cpu_data; #else my_cpu_data = cpu_data(smp_processor_id()); + my_cpu_data->mmu_gathers = &mmu_gathers[smp_processor_id()]; #endif /* diff -Nru a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c --- a/arch/ia64/mm/init.c Fri Dec 12 16:27:39 2003 +++ b/arch/ia64/mm/init.c Fri Dec 12 16:27:39 2003 @@ -28,9 +28,6 @@ #include #include #include -#include - -mmu_gather_t mmu_gathers[NR_CPUS]; /* References to section boundaries: */ extern char _stext, _etext, _edata, __init_begin, __init_end; diff -Nru a/drivers/char/Config.in b/drivers/char/Config.in --- a/drivers/char/Config.in Fri Dec 12 16:27:39 2003 +++ b/drivers/char/Config.in Fri Dec 12 16:27:39 2003 @@ -24,6 +24,9 @@ tristate ' Atomwide serial port support' CONFIG_ATOMWIDE_SERIAL tristate ' Dual serial port support' CONFIG_DUALSP_SERIAL fi + if [ "$CONFIG_ACPI" = "y" ]; then + bool ' Support for serial ports defined in ACPI namespace' CONFIG_SERIAL_ACPI + fi fi dep_mbool 'Extended dumb serial driver options' CONFIG_SERIAL_EXTENDED $CONFIG_SERIAL if [ "$CONFIG_SERIAL_EXTENDED" = "y" ]; then diff -Nru a/drivers/char/serial.c b/drivers/char/serial.c --- a/drivers/char/serial.c Fri Dec 12 16:27:39 2003 +++ b/drivers/char/serial.c Fri Dec 12 16:27:39 2003 @@ -92,9 +92,8 @@ * ever possible. * * CONFIG_SERIAL_ACPI - * Enable support for serial console port and serial - * debug port as defined by the SPCR and DBGP tables in - * ACPI 2.0. + * Enable support for serial ports found in the ACPI + * namespace. */ #include @@ -222,6 +221,10 @@ #ifdef CONFIG_MAGIC_SYSRQ #include #endif +#ifdef ENABLE_SERIAL_ACPI +#include +#include +#endif /* * All of the compatibilty code so we can compile serial.c against @@ -257,6 +260,10 @@ static struct timer_list serial_timer; +#define HP_DIVA_CHECKTIME (1*HZ) +static struct timer_list hp_diva_timer; +static int hp_diva_count = 0; + /* serial subtype definitions */ #ifndef SERIAL_TYPE_NORMAL #define SERIAL_TYPE_NORMAL 1 @@ -793,6 +800,41 @@ } #ifdef CONFIG_SERIAL_SHARE_IRQ +static inline int is_hp_diva_info(struct async_struct *info) +{ + struct pci_dev *dev = info->state->dev; + return (dev && dev->vendor == PCI_VENDOR_ID_HP && + dev->device == PCI_DEVICE_ID_HP_SAS); +} + +static inline int is_hp_diva_irq(int irq) +{ + struct async_struct *info = IRQ_ports[irq]; + return (info && is_hp_diva_info(info)); +} + +/* + * It is possible to "use up" transmit empty interrupts in some + * cases with HP Diva cards. Figure out if there _should_ be a + * transmit interrupt and if so, return a suitable iir value so + * that we can recover when called from rs_timer(). + */ +static inline int hp_diva_iir(int irq, struct async_struct *info) +{ + int iir = serial_in(info, UART_IIR); + + if (is_hp_diva_info(info) && + (iir & UART_IIR_NO_INT) != 0 && + (info->IER & UART_IER_THRI) != 0 && + (info->xmit.head != info->xmit.tail || info->x_char) && + (serial_in(info, UART_LSR) & UART_LSR_THRE) != 0) { + iir &= ~(UART_IIR_ID | UART_IIR_NO_INT); + iir |= UART_IIR_THRI; + } + + return iir; +} + /* * This is the serial driver's generic interrupt routine */ @@ -823,7 +865,7 @@ do { if (!info->tty || - ((iir=serial_in(info, UART_IIR)) & UART_IIR_NO_INT)) { + ((iir=hp_diva_iir(irq, info)) & UART_IIR_NO_INT)) { if (!end_mark) end_mark = info; goto next; @@ -1097,9 +1139,11 @@ #ifdef CONFIG_SERIAL_SHARE_IRQ if (info->next_port) { do { - serial_out(info, UART_IER, 0); - info->IER |= UART_IER_THRI; - serial_out(info, UART_IER, info->IER); + if (!is_hp_diva_info(info)) { + serial_out(info, UART_IER, 0); + info->IER |= UART_IER_THRI; + serial_out(info, UART_IER, info->IER); + } info = info->next_port; } while (info); #ifdef CONFIG_SERIAL_MULTIPORT @@ -1131,6 +1175,35 @@ } /* + * This subroutine is called when the hp_diva_timer goes off. In + * certain cases (multiple gettys in particular) Diva seems to issue + * only a single transmit empty interrupt instead of one each time + * THRI is enabled, causing interrupts to be "used up". This serves + * to poll the Diva UARTS more frequently than rs_timer() does. + */ +static void hp_diva_check(unsigned long dummy) +{ +#ifdef CONFIG_SERIAL_SHARE_IRQ + static unsigned long last_strobe; + unsigned long flags; + int i; + + if (time_after_eq(jiffies, last_strobe + HP_DIVA_CHECKTIME)) { + for (i = 0; i < NR_IRQS; i++) { + if (is_hp_diva_irq(i)) { + save_flags(flags); cli(); + rs_interrupt(i, NULL, NULL); + restore_flags(flags); + } + } + } + last_strobe = jiffies; + mod_timer(&hp_diva_timer, jiffies + HP_DIVA_CHECKTIME); +#endif +} + + +/* * --------------------------------------------------------------- * Low level utility subroutines for the serial driver: routines to * figure out the appropriate timeout for an interrupt chain, routines @@ -4294,6 +4367,12 @@ break; } + if (hp_diva_count++ == 0) { + init_timer(&hp_diva_timer); + hp_diva_timer.function = hp_diva_check; + mod_timer(&hp_diva_timer, jiffies + HP_DIVA_CHECKTIME); + } + return 0; } @@ -4597,6 +4676,129 @@ } } +#ifdef ENABLE_SERIAL_ACPI +static acpi_status acpi_serial_address(struct serial_struct *req, + struct acpi_resource_address64 *addr) +{ + unsigned long size; + + size = addr->max_address_range - addr->min_address_range + 1; + req->iomem_base = ioremap(addr->min_address_range, size); + if (!req->iomem_base) { + printk("%s: couldn't ioremap 0x%lx-0x%lx\n", __FUNCTION__, + addr->min_address_range, addr->max_address_range); + return AE_ERROR; + } + req->io_type = SERIAL_IO_MEM; + return AE_OK; +} + +static acpi_status acpi_serial_ext_irq(struct serial_struct *req, + struct acpi_resource_ext_irq *ext_irq) +{ + if (ext_irq->number_of_interrupts > 0) { +#ifdef CONFIG_IA64 + req->irq = acpi_register_irq(ext_irq->interrupts[0], + ext_irq->active_high_low, ext_irq->edge_level); +#else + req->irq = ext_irq->interrupts[0]; +#endif + } + return AE_OK; +} + +static acpi_status acpi_serial_port(struct serial_struct *req, + struct acpi_resource_io *io) +{ + req->port = io->min_base_address; + req->io_type = SERIAL_IO_PORT; + return AE_OK; +} + +static acpi_status acpi_serial_irq(struct serial_struct *req, + struct acpi_resource_irq *irq) +{ + if (irq->number_of_interrupts > 0) { +#ifdef CONFIG_IA64 + req->irq = acpi_register_irq(irq->interrupts[0], + irq->active_high_low, irq->edge_level); +#else + req->irq = irq->interrupts[0]; +#endif + } + return AE_OK; +} + +static acpi_status acpi_serial_resource(struct acpi_resource *res, void *data) +{ + struct serial_struct *serial_req = (struct serial_struct *) data; + struct acpi_resource_address64 addr; + acpi_status status; + + status = acpi_resource_to_address64(res, &addr); + if (ACPI_SUCCESS(status)) + return acpi_serial_address(serial_req, &addr); + else if (res->id == ACPI_RSTYPE_EXT_IRQ) + return acpi_serial_ext_irq(serial_req, &res->data.extended_irq); + else if (res->id == ACPI_RSTYPE_IO) + return acpi_serial_port(serial_req, &res->data.io); + else if (res->id == ACPI_RSTYPE_IRQ) + return acpi_serial_irq(serial_req, &res->data.irq); + return AE_OK; +} + +static int acpi_serial_add(struct acpi_device *device) +{ + acpi_status status; + struct serial_struct serial_req; + int line; + + memset(&serial_req, 0, sizeof(serial_req)); + + status = acpi_walk_resources(device->handle, METHOD_NAME__CRS, + acpi_serial_resource, &serial_req); + if (ACPI_FAILURE(status)) + return -ENODEV; + + if (!serial_req.iomem_base && !serial_req.port) { + printk("%s: no iomem or port address in %s _CRS\n", __FUNCTION__, + device->pnp.bus_id); + return -ENODEV; + } + + serial_req.baud_base = BASE_BAUD; + serial_req.flags = ASYNC_SKIP_TEST|ASYNC_BOOT_AUTOCONF|ASYNC_AUTO_IRQ; + serial_req.xmit_fifo_size = serial_req.custom_divisor = 0; + serial_req.close_delay = serial_req.hub6 = serial_req.closing_wait = 0; + serial_req.iomem_reg_shift = 0; + + line = register_serial(&serial_req); + if (line < 0) + return -ENODEV; + + return 0; +} + +static int acpi_serial_remove(struct acpi_device *device, int type) +{ + return 0; +} + +static struct acpi_driver acpi_serial_driver = { + .name = "serial", + .class = "", + .ids = "PNP0501", + .ops = { + .add = acpi_serial_add, + .remove = acpi_serial_remove, + }, +}; + +static void __devinit probe_serial_acpi(void) +{ + acpi_bus_register_driver(&acpi_serial_driver); +} +#endif /* ENABLE_SERIAL_ACPI */ static struct pci_device_id serial_pci_tbl[] __devinitdata = { { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960, @@ -5558,6 +5760,9 @@ tty_register_devfs(&callout_driver, 0, callout_driver.minor_start + state->line); } +#ifdef ENABLE_SERIAL_ACPI + probe_serial_acpi(); +#endif #ifdef ENABLE_SERIAL_PCI probe_serial_pci(); #endif @@ -5735,6 +5940,8 @@ /* printk("Unloading %s: version %s\n", serial_name, serial_version); */ del_timer_sync(&serial_timer); + if (hp_diva_count > 0) + del_timer_sync(&hp_diva_timer); save_flags(flags); cli(); remove_bh(SERIAL_BH); if ((e1 = tty_unregister_driver(&serial_driver))) diff -Nru a/fs/Config.in b/fs/Config.in --- a/fs/Config.in Fri Dec 12 16:27:40 2003 +++ b/fs/Config.in Fri Dec 12 16:27:40 2003 @@ -54,6 +54,13 @@ bool 'Virtual memory file system support (former shm fs)' CONFIG_TMPFS define_bool CONFIG_RAMFS y +bool 'HugeTLB file system support' CONFIG_HUGETLBFS +if [ "$CONFIG_HUGETLBFS" = "y" ] ; then + define_bool CONFIG_HUGETLB_PAGE y +else + define_bool CONFIG_HUGETLB_PAGE n +fi + tristate 'ISO 9660 CDROM file system support' CONFIG_ISO9660_FS dep_mbool ' Microsoft Joliet CDROM extensions' CONFIG_JOLIET $CONFIG_ISO9660_FS dep_mbool ' Transparent decompression extension' CONFIG_ZISOFS $CONFIG_ISO9660_FS @@ -72,13 +79,17 @@ bool '/proc file system support' CONFIG_PROC_FS -# For some reason devfs corrupts memory badly on x86-64. Disable it -# for now. -if [ "$CONFIG_X86_64" != "y" ] ; then -dep_bool '/dev file system support (EXPERIMENTAL)' CONFIG_DEVFS_FS $CONFIG_EXPERIMENTAL +if [ "$CONFIG_IA64_SGI_SN2" = "y" ] ; then + define_bool CONFIG_DEVFS_FS y +else + # For some reason devfs corrupts memory badly on x86-64. Disable it + # for now. + if [ "$CONFIG_X86_64" != "y" ] ; then + dep_bool '/dev file system support (EXPERIMENTAL)' CONFIG_DEVFS_FS $CONFIG_EXPERIMENTAL + fi +fi dep_bool ' Automatically mount at boot' CONFIG_DEVFS_MOUNT $CONFIG_DEVFS_FS dep_bool ' Debug devfs' CONFIG_DEVFS_DEBUG $CONFIG_DEVFS_FS -fi # It compiles as a module for testing only. It should not be used # as a module in general. If we make this "tristate", a bunch of people diff -Nru a/fs/Makefile b/fs/Makefile --- a/fs/Makefile Fri Dec 12 16:27:39 2003 +++ b/fs/Makefile Fri Dec 12 16:27:39 2003 @@ -28,6 +28,7 @@ subdir-$(CONFIG_EXT2_FS) += ext2 subdir-$(CONFIG_CRAMFS) += cramfs subdir-$(CONFIG_RAMFS) += ramfs +subdir-$(CONFIG_HUGETLBFS) += hugetlbfs subdir-$(CONFIG_CODA_FS) += coda subdir-$(CONFIG_INTERMEZZO_FS) += intermezzo subdir-$(CONFIG_MINIX_FS) += minix diff -Nru a/fs/inode.c b/fs/inode.c --- a/fs/inode.c Fri Dec 12 16:27:40 2003 +++ b/fs/inode.c Fri Dec 12 16:27:40 2003 @@ -56,7 +56,7 @@ */ static LIST_HEAD(inode_in_use); -static LIST_HEAD(inode_unused); +LIST_HEAD(inode_unused); static struct list_head *inode_hashtable; static LIST_HEAD(anon_hash_chain); /* for inodes with NULL i_sb */ diff -Nru a/include/asm-ia64/xor.h b/include/asm-ia64/xor.h --- a/include/asm-ia64/xor.h Fri Dec 12 16:27:39 2003 +++ b/include/asm-ia64/xor.h Fri Dec 12 16:27:39 2003 @@ -13,6 +13,7 @@ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include extern void xor_ia64_2(unsigned long, unsigned long *, unsigned long *); extern void xor_ia64_3(unsigned long, unsigned long *, unsigned long *, @@ -30,4 +31,11 @@ do_5: xor_ia64_5, }; -#define XOR_TRY_TEMPLATES xor_speed(&xor_block_ia64) +#define XOR_TRY_TEMPLATES do { \ + xor_speed(&xor_block_8regs); \ + xor_speed(&xor_block_8regs_p); \ + xor_speed(&xor_block_32regs); \ + xor_speed(&xor_block_32regs_p); \ + xor_speed(&xor_block_ia64); \ + } while(0) + diff -Nru a/include/asm-m68k/pgtable.h b/include/asm-m68k/pgtable.h --- a/include/asm-m68k/pgtable.h Fri Dec 12 16:27:40 2003 +++ b/include/asm-m68k/pgtable.h Fri Dec 12 16:27:40 2003 @@ -180,6 +180,24 @@ #ifndef __ASSEMBLY__ #include + +/* + * Macro to mark a page protection value as "uncacheable". + */ +#ifdef SUN3_PAGE_NOCACHE +# define __SUN3_PAGE_NOCACHE SUN3_PAGE_NOCACHE +#else +# define __SUN3_PAGE_NOCACHE 0 +#endif +#define pgprot_noncached(prot) \ + (MMU_IS_SUN3 \ + ? (__pgprot(pgprot_val(prot) | __SUN3_PAGE_NOCACHE)) \ + : ((MMU_IS_851 || MMU_IS_030) \ + ? (__pgprot(pgprot_val(prot) | _PAGE_NOCACHE030)) \ + : (MMU_IS_040 || MMU_IS_060) \ + ? (__pgprot((pgprot_val(prot) & _CACHEMASK040) | _PAGE_NOCACHE_S)) \ + : (prot))) + #endif /* !__ASSEMBLY__ */ /* diff -Nru a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h --- a/include/asm-ppc/pgtable.h Fri Dec 12 16:27:39 2003 +++ b/include/asm-ppc/pgtable.h Fri Dec 12 16:27:39 2003 @@ -587,6 +587,11 @@ pte_update(ptep, 0, _PAGE_DIRTY); } +/* + * Macro to mark a page protection value as "uncacheable". + */ +#define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_NO_CACHE | _PAGE_GUARDED)) + #define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HASHPTE) == 0) #define pmd_page(pmd) (pmd_val(pmd) & PAGE_MASK) diff -Nru a/include/linux/fs.h b/include/linux/fs.h --- a/include/linux/fs.h Fri Dec 12 16:27:39 2003 +++ b/include/linux/fs.h Fri Dec 12 16:27:39 2003 @@ -247,7 +247,7 @@ /* First cache line: */ struct buffer_head *b_next; /* Hash queue list */ unsigned long b_blocknr; /* block number */ - unsigned short b_size; /* block size */ + unsigned int b_size; /* block size */ unsigned short b_list; /* List that this buffer appears */ kdev_t b_dev; /* device (B_FREE = free) */ diff -Nru a/include/linux/sysctl.h b/include/linux/sysctl.h --- a/include/linux/sysctl.h Fri Dec 12 16:27:39 2003 +++ b/include/linux/sysctl.h Fri Dec 12 16:27:39 2003 @@ -156,6 +156,7 @@ VM_MAPPED_RATIO=20, /* amount of unfreeable pages that triggers swapout */ VM_LAPTOP_MODE=21, /* kernel in laptop flush mode */ VM_BLOCK_DUMP=22, /* dump fs activity to log */ + VM_HUGETLB_PAGES=23, /* int: Number of available Huge Pages */ }; diff -Nru a/mm/page_alloc.c b/mm/page_alloc.c --- a/mm/page_alloc.c Fri Dec 12 16:27:39 2003 +++ b/mm/page_alloc.c Fri Dec 12 16:27:39 2003 @@ -49,11 +49,11 @@ /* * Temporary debugging check. */ -#define BAD_RANGE(zone, page) \ -( \ - (((page) - mem_map) >= ((zone)->zone_start_mapnr+(zone)->size)) \ - || (((page) - mem_map) < (zone)->zone_start_mapnr) \ - || ((zone) != page_zone(page)) \ +#define BAD_RANGE(zone, page) \ +( \ + (((page) - mem_map) >= ((zone)->zone_start_mapnr+(zone)->size)) \ + || (((page) - mem_map) < (zone)->zone_start_mapnr) \ + || ((zone) != page_zone(page)) \ ) /* @@ -575,7 +575,7 @@ unsigned long nr, total, flags; total = 0; - if (zone->size) { + if (zone->realsize) { spin_lock_irqsave(&zone->lock, flags); for (order = 0; order < MAX_ORDER; order++) { head = &(zone->free_area + order)->free_list; @@ -607,13 +607,44 @@ /* * Builds allocation fallback zone lists. */ -static inline void build_zonelists(pg_data_t *pgdat) +static int __init build_zonelists_node(pg_data_t *pgdat, zonelist_t *zonelist, int j, int k) { - int i, j, k; + zone_t *zone; + switch (k) { + default: + BUG(); + /* + * fallthrough: + */ + case ZONE_HIGHMEM: + zone = pgdat->node_zones + ZONE_HIGHMEM; + if (zone->realsize) { +#ifndef CONFIG_HIGHMEM + BUG(); +#endif + zonelist->zones[j++] = zone; + } + case ZONE_NORMAL: + zone = pgdat->node_zones + ZONE_NORMAL; + if (zone->realsize) + zonelist->zones[j++] = zone; + case ZONE_DMA: + zone = pgdat->node_zones + ZONE_DMA; + if (zone->realsize) + zonelist->zones[j++] = zone; + } + + return j; +} + +static void __init build_zonelists(pg_data_t *pgdat) +{ + int i, j, k, node, local_node; + local_node = pgdat->node_id; + printk("Building zonelist for node : %d\n", local_node); for (i = 0; i <= GFP_ZONEMASK; i++) { zonelist_t *zonelist; - zone_t *zone; zonelist = pgdat->node_zonelists + i; memset(zonelist, 0, sizeof(*zonelist)); @@ -625,33 +656,32 @@ if (i & __GFP_DMA) k = ZONE_DMA; - switch (k) { - default: - BUG(); - /* - * fallthrough: - */ - case ZONE_HIGHMEM: - zone = pgdat->node_zones + ZONE_HIGHMEM; - if (zone->size) { -#ifndef CONFIG_HIGHMEM - BUG(); -#endif - zonelist->zones[j++] = zone; - } - case ZONE_NORMAL: - zone = pgdat->node_zones + ZONE_NORMAL; - if (zone->size) - zonelist->zones[j++] = zone; - case ZONE_DMA: - zone = pgdat->node_zones + ZONE_DMA; - if (zone->size) - zonelist->zones[j++] = zone; - } + j = build_zonelists_node(pgdat, zonelist, j, k); + /* + * Now we build the zonelist so that it contains the zones + * of all the other nodes. + * We don't want to pressure a particular node, so when + * building the zones for node N, we make sure that the + * zones coming right after the local ones are those from + * node N+1 (modulo N) + */ + for (node = local_node + 1; node < numnodes; node++) + j = build_zonelists_node(NODE_DATA(node), zonelist, j, k); + for (node = 0; node < local_node; node++) + j = build_zonelists_node(NODE_DATA(node), zonelist, j, k); + zonelist->zones[j++] = NULL; } } +void __init build_all_zonelists(void) +{ + int i; + + for(i = 0 ; i < numnodes ; i++) + build_zonelists(NODE_DATA(i)); +} + /* * Helper functions to size the waitqueue hash table. * Essentially these want to choose hash table sizes sufficiently @@ -694,6 +724,31 @@ return ffz(~size); } +static unsigned long memmap_init(struct page *start, struct page *end, + int zone, unsigned long start_paddr, int highmem) +{ + struct page *page; + + for (page = start; page < end; page++) { + set_page_zone(page, zone); + set_page_count(page, 0); + SetPageReserved(page); + INIT_LIST_HEAD(&page->list); + if (!highmem) + set_page_address(page, __va(start_paddr)); + start_paddr += PAGE_SIZE; + } + return start_paddr; +} + +#ifdef HAVE_ARCH_MEMMAP_INIT +#define MEMMAP_INIT(start, end, zone, paddr, highmem) \ + arch_memmap_init(memmap_init, start, end, zone, paddr, highmem) +#else +#define MEMMAP_INIT(start, end, zone, paddr, highmem) \ + memmap_init(start, end, zone, paddr, highmem) +#endif + #define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1)) /* @@ -715,10 +770,8 @@ BUG(); totalpages = 0; - for (i = 0; i < MAX_NR_ZONES; i++) { - unsigned long size = zones_size[i]; - totalpages += size; - } + for (i = 0; i < MAX_NR_ZONES; i++) + totalpages += zones_size[i]; realtotalpages = totalpages; if (zholes_size) for (i = 0; i < MAX_NR_ZONES; i++) @@ -727,7 +780,7 @@ printk("On node %d totalpages: %lu\n", nid, realtotalpages); /* - * Some architectures (with lots of mem and discontinous memory + * Some architectures (with lots of mem and discontigous memory * maps) have to search for a good mem_map area: * For discontigmem, the conceptual mem map array starts from * PAGE_OFFSET, we need to align the actual array onto a mem map @@ -740,7 +793,7 @@ MAP_ALIGN((unsigned long)lmem_map - PAGE_OFFSET)); } *gmap = pgdat->node_mem_map = lmem_map; - pgdat->node_size = totalpages; + pgdat->node_size = 0; pgdat->node_start_paddr = zone_start_paddr; pgdat->node_start_mapnr = (lmem_map - mem_map); pgdat->nr_zones = 0; @@ -757,7 +810,7 @@ if (zholes_size) realsize -= zholes_size[j]; - printk("zone(%lu): %lu pages.\n", j, size); + printk("zone(%lu): %lu pages.\n", j, realsize); zone->size = size; zone->realsize = realsize; zone->name = zone_names[j]; @@ -768,6 +821,7 @@ zone->nr_active_pages = zone->nr_inactive_pages = 0; + pgdat->node_size += realsize; if (!size) continue; @@ -828,16 +882,10 @@ * up by free_all_bootmem() once the early boot process is * done. Non-atomic initialization, single-pass. */ - for (i = 0; i < size; i++) { - struct page *page = mem_map + offset + i; - set_page_zone(page, nid * MAX_NR_ZONES + j); - set_page_count(page, 0); - SetPageReserved(page); - INIT_LIST_HEAD(&page->list); - if (j != ZONE_HIGHMEM) - set_page_address(page, __va(zone_start_paddr)); - zone_start_paddr += PAGE_SIZE; - } + zone_start_paddr = MEMMAP_INIT(mem_map + offset, + mem_map + offset + size, + nid * MAX_NR_ZONES + j, zone_start_paddr, + (j == ZONE_HIGHMEM ? 1 : 0)); offset += size; for (i = 0; ; i++) { @@ -878,7 +926,6 @@ (unsigned long *) alloc_bootmem_node(pgdat, bitmap_size); } } - build_zonelists(pgdat); } void __init free_area_init(unsigned long *zones_size)